﻿using MaterialWinforms.Animations;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;

namespace MaterialWinforms.Controls
{
    public class MaterialRaisedButton : Button, IShadowedMaterialControl
    {
        [Browsable(false)]
        public int Depth { get; set; }

        [Browsable(false)]
        public MaterialWinformsManager SkinManager { get { return MaterialWinformsManager.Instance; } }

        [Browsable(false)]
        public MouseState MouseState { get; set; }

        public bool Primary { get; set; }

        public int Elevation { get; set; }

        [Browsable(false)]
        public GraphicsPath ShadowBorder { get; set; }

        private Image _icon;
        public Image Icon
        {
            get { return _icon; }
            set
            {
                _icon = value;
                if (AutoSize)
                    Size = GetPreferredSize();
                Invalidate();
            }
        }

        private ToolTip tooltipControl;

        private string _toolTip = "";
        public string ToolTip
        {
            get
            {
                return _toolTip;
            }
            set
            {
                _toolTip = value;
                if (_toolTip != "")
                {
                    tooltipControl.SetToolTip(this, _toolTip);
                }
                else
                {
                    tooltipControl.RemoveAll();
                }
            }
        }

        private int _cornerRadius = 8;
        public int CornerRadius
        {
            get
            {
                return _cornerRadius;
            }
            set
            {
                if (value < 0 || value > 180)
                {
                    return;
                }
                _cornerRadius = value;
                Invalidate();
            }
        }

        private Color _backColor;
        public override Color BackColor
        {
            get
            {
                return _backColor;
            }
            set
            {
                _backColor = value;
                Invalidate();
            }
        }

        private bool _isBordered = false;
        public bool IsBordered
        {
            get
            {
                return _isBordered;
            }
            set
            {
                _isBordered = value;
                Invalidate();
            }
        }

        private bool isMouseEnter = false;

        private readonly AnimationManager animationManager;

        public MaterialRaisedButton()
        {
            // 自身的一些属性
            Primary = true;
            Elevation = 5;
            _backColor = Primary ? SkinManager.ColorScheme.PrimaryColor : SkinManager.GetRaisedButtonBackroundColor();
            Font = new Font("微软雅黑", 12F);

            // 提示窗口的属性
            tooltipControl = new ToolTip
            {
                InitialDelay = 500,
                ReshowDelay = 500,
                AutomaticDelay = 500,
                AutoPopDelay = 20000,
                ShowAlways = true
            };

            // 一些方法
            animationManager = new AnimationManager(false)
            {
                Increment = 0.03,
                AnimationType = AnimationType.EaseOut
            };
            animationManager.OnAnimationProgress += sender => Invalidate();
        }

        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            base.OnMouseUp(mevent);

            isMouseEnter = true;
            animationManager.StartNewAnimation(AnimationDirection.In, mevent.Location);
            Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs mevent)
        {
            base.OnMouseDown(mevent);

            isMouseEnter = false;
            Invalidate();
        }

        protected override void OnLocationChanged(System.EventArgs e)
        {
            base.OnLocationChanged(e);
            ShadowBorder = new GraphicsPath();
            ShadowBorder.AddRectangle(new Rectangle(this.Location.X, this.Location.Y, Width, Height));
        }

        void MaterialCard_MouseLeave(object sender, System.EventArgs e)
        {
            isMouseEnter = false;
            Elevation /= 2;
            Refresh();
        }

        void MaterialCard_MouseEnter(object sender, System.EventArgs e)
        {
            isMouseEnter = true;
            Elevation *= 2;
            Refresh();
        }

        protected override void OnResize(System.EventArgs e)
        {
            base.OnResize(e);
            ShadowBorder = new GraphicsPath();
            ShadowBorder.AddRectangle(new Rectangle(this.Location.X, this.Location.Y, Width, Height));
        }

        private Color GetBackgroundColor()
        {
            return isMouseEnter ? (this.BackColor.A - 20 >= 0 ? Color.FromArgb(this.BackColor.A - 20, this.BackColor) : this.BackColor) : this.BackColor;
        }

        protected override void OnPaint(PaintEventArgs pevent)
        {
            var g = pevent.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextRenderingHint.AntiAlias;

            g.Clear(Parent.BackColor);

            using (var backgroundPath = DrawHelper.CreateRoundRect(ClientRectangle.X,
                ClientRectangle.Y,
                this.Width,
                this.Height,
                1f))
            {
                g.FillPath(new SolidBrush(GetBackgroundColor()), backgroundPath);
            }

            if (animationManager.IsAnimating())
            {
                for (int i = 0; i < animationManager.GetAnimationCount(); i++)
                {
                    var animationValue = animationManager.GetProgress(i);
                    var animationSource = animationManager.GetSource(i);
                    var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationValue * 50)), Color.White));
                    var rippleSize = (int)(animationValue * Width * 2);
                    g.FillEllipse(rippleBrush, new Rectangle(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
                }
            }

            g.DrawString(
                Text.ToUpper(),
                this.Font,
                SkinManager.GetRaisedButtonTextBrush(Primary),
                ClientRectangle,
                new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });

            if (_isBordered)
            {
                pevent.Graphics.DrawPath(new Pen(Color.Black, 2), DrawHelper.GetRoundedRectPath(ClientRectangle, _cornerRadius));
            }
            this.Region = new Region(DrawHelper.GetRoundedRectPath(ClientRectangle, _cornerRadius));
        }

        private Size GetPreferredSize()
        {
            return GetPreferredSize(new Size(0, 0));
        }

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            MouseEnter += MaterialCard_MouseEnter;
            MouseLeave += MaterialCard_MouseLeave;
        }
    }
}
